package io.github.flypiggy.stack.operate.log.spring.boot.starter.configuration;

import io.github.flypiggy.stack.operate.log.spring.boot.starter.aop.LogAspect;
import io.github.flypiggy.stack.operate.log.spring.boot.starter.context.OperatorGetter;
import io.github.flypiggy.stack.operate.log.spring.boot.starter.datasource.DatasourceApi;
import io.github.flypiggy.stack.operate.log.spring.boot.starter.exception.OperateLogException;
import io.github.flypiggy.stack.operate.log.spring.boot.starter.properties.Elasticsearch;
import io.github.flypiggy.stack.operate.log.spring.boot.starter.properties.Jdbc;
import io.github.flypiggy.stack.operate.log.spring.boot.starter.properties.OperateLogProperties;
import io.github.flypiggy.stack.operate.log.spring.boot.starter.properties.enums.DatasourceEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

public class LogAspectBase {
    private final Logger log = LoggerFactory.getLogger(LogAspectBase.class);

    protected final OperatorGetter operatorGetter;
    protected final OperateLogProperties operateLogProperties;

    protected LogAspectBase(OperatorGetter operatorGetter, OperateLogProperties operateLogProperties) {
        this.operatorGetter = operatorGetter;
        this.operateLogProperties = operateLogProperties;
    }

    protected LogAspect logAspectInitializer(DatasourceApi datasourceApi) {
        this.checkProperties();
        return new LogAspect(datasourceApi, operateLogProperties, operatorGetter);
    }

    private void checkProperties() throws OperateLogException {
        if (null == operateLogProperties.getStoreType()) {
            throw new OperateLogException("Please configure parameters 'spring.operate-log.store-type'!");
        }
        if (DatasourceEnum.JDBC.equals(operateLogProperties.getStoreType())) {
            Jdbc jdbc = operateLogProperties.getJdbc();
            if (Objects.isNull(jdbc)) {
                throw new OperateLogException("Please check the package path in the configuration file! \n\tproperties: spring.operate-log.jdbc");
            }
        } else if (DatasourceEnum.ELASTICSEARCH.equals(operateLogProperties.getStoreType())) {
            Elasticsearch elasticsearch = operateLogProperties.getElasticsearch();
            if (Objects.isNull(elasticsearch)) {
                throw new OperateLogException("Please check the package path in the configuration file! \n\tproperties: spring.operate-log.elasticsearch");
            }
            String indexName = elasticsearch.getIndex().getName();
            if (Objects.isNull(indexName) || "".equals(indexName)) {
                throw new OperateLogException("Please check the package path in the configuration file! \n\tproperties: spring.operate-log.elasticsearch.index-name");
            }
            if (!indexName.toLowerCase().equals(indexName)) {
                throw new OperateLogException("Please check configuration file properties \"spring.operate-log.elasticsearch.index-name\", don't use capital letters");
            }
        }
        // Check whether swagger dependency is introduced
        if (operateLogProperties.getUseSwaggerAnnotation().equals(Boolean.TRUE)) {
            try {
                Class.forName("io.swagger.annotations.Api");
            } catch (ClassNotFoundException e) {
                throw new OperateLogException("If you need to mark log operation records with swagger annotations, you need to introduce swagger dependencies. If you do not need it, you need to configure it. \n\tproperties: spring.operate-log.use-swagger-annotation=false");
            }
        }
        log.info("OPERATE-LOG We will use {} as the data source for storing operation logs.", operateLogProperties.getStoreType());
    }
}
